import re
from django.http import JsonResponse
from django.utils.deprecation import MiddlewareMixin
import redis
import json
from jwt import DecodeError, ExpiredSignatureError
from rest_framework_jwt.utils import jwt_decode_handler



class MyRBAC(MiddlewareMixin):

    # 初始化
    def __init__(self, handler):
        super(MyRBAC, self).__init__(handler)

        # 初始化redis连接
        self.redis_cli = redis.Redis(db=3)

    # 预处理请求
    def process_request(self, request):
        # 1 获取请求的方法 路径
        method = request.method.lower()    # 请求方法
        path_info = request.path_info[1:]  # 请求路由 分片 从下标为1开始 去掉开头的/

        # 2 判断当前请求是否为 登录 ,^admin ,sms_code
        # 放过这些请求 不需要拦截     re.I 忽略大小写
        if re.findall(r"login|^admin|sms_code", path_info, re.I):
            # 放过去
            return None

        # 3 其他的常规请求
        # 验证是否登录 鉴权
        payload = self.validate_token(request)

        if payload:   # 已经登录
            # 4 判断当前用户对当前访问的url 是否有访问的权限
            print('解析的payload数据----->>>>', payload)

            # 根据用户id获取他的所有权限
            key = 'user_permissions_%s' % (payload.get('user_id'))
            # 获取权限列表          内存中存储的权限key: '[1,2,3,....]'
            permissions_list = json.loads(self.redis_cli.get(key).decode())


            # 检查权限能否与请求的路由匹配上
            for i in permissions_list:   # i ====> get ^users/permission/$
                if i.startswith(method):  # 使用请求方法开头
                    # 进一步匹配正则部分的路由
                    re_path = i.split()[1]
                    if re.findall(re_path, path_info, re.I):
                        return None

            # 不具有访问权限
            return JsonResponse({'code': 403, 'msg': '没有访问权限'})


        else:  # 没有登录
            return JsonResponse({'code': 403, 'msg': '没有登录'})



    @staticmethod
    def validate_token(request):
        # 获取前端请求头的 Authorization
        token = request.headers.get('Authorization')
        if not token:
            return False
            # return JsonResponse({'code': 400, 'msg': '没有提交token'})
        token = token.split()[1]

        # 解码token
        try:
            payload = jwt_decode_handler(token)
        except DecodeError:
            return False
        except ExpiredSignatureError:
            return False

        return payload


    # def process_view(self, request, callback, *args, **kwargs):
    #     ...
    # def process_exception(self, request, exception,):
    #     ...

















